<template>
  <div :style="{ height: height + 'px', zIndex: zIndex }">
    <div
      :class="className"
      :style="{
        top: isSticky ? stickyTop + 'px' : '',
        zIndex: zIndex,
        position: position,
        width: width,
        height: height + 'px',
      }"
    >
      <slot>
        <div>sticky</div>
      </slot>
    </div>
  </div>
</template>

<script setup name="Sticky">
import { onActivated, onMounted, onUnmounted } from 'vue'
const { proxy } = getCurrentInstance()
const props = defineProps({
  stickyTop: {
    type: Number,
    default: 0,
  },
  zIndex: {
    type: Number,
    default: 1,
  },
  className: {
    type: String,
    default: '',
  },
})
const active = ref(false)
const position = ref('')
const width = ref(undefined)
const height = ref(undefined)
const isSticky = ref(false)

function sticky() {
  if (active.value) {
    return
  }
  position.value = 'fixed'
  active.value = true
  width.value = width.value + 'px'
  isSticky.value = true
}
function handleReset() {
  if (!active.value) {
    return
  }
  reset()
}
function reset() {
  position.value = ''
  width.value = 'auto'
  active.value = false
  isSticky.value = false
}
function handleScroll() {
  const width = proxy.$el.getBoundingClientRect().width
  width.value = width || 'auto'
  const offsetTop = proxy.$el.getBoundingClientRect().top
  if (offsetTop < props.stickyTop) {
    sticky()
    return
  }
  handleReset()
}
function handleResize() {
  if (isSticky.value) {
    width.value = proxy.$el.getBoundingClientRect().width + 'px'
  }
}

onMounted(() => {
  height.value = proxy.$el.getBoundingClientRect().height
  window.addEventListener('scroll', handleScroll)
  window.addEventListener('resize', handleResize)
})
onActivated(() => {
  handleScroll()
})
onUnmounted(() => {
  window.removeEventListener('scroll', handleScroll)
  window.removeEventListener('resize', handleResize)
})
</script>
